import { Service } from 'egg';
import Result from '../utils/Result';
const svgCaptcha = require('svg-captcha');

export default class User extends Service {

  /**
     * 用户注册
     */
  public async registerService() {
    const { ctx } = this;
    const { userName, passWord } = ctx.request.body;
    const data = {
      userName,
      passWord: ctx.helper.bcryptData(passWord),
    };

    const getDataOne = await ctx.model.User.findOne({
      where: {
        userName: data?.userName,
      },
    });
    if (getDataOne) {
      return Result.setData({
        code: 1,
        msg: '用户名已存在',
      });
    }
    const insetData = await ctx.model.User.create(data);
    ctx.logger.info(data, '---------------------注册成功');
    return Result.setData({
      code: 0,
      msg: '保存成功',
      data: insetData,
    });
  }

  /**
     * 用户登录
     */
  public async login() {
    const { ctx } = this;
    const { userName, passWord ,captcha} = ctx.request.body;
    const data = {
      userName,
      passWord,
    };
    let captchaKey = await ctx.app.redis.get(ctx.cookies.get("captchaKey"));
    console.log(captchaKey,'..........................')
    if(!captchaKey){
      return Result.setData({
        code: 1,
        msg: '验证码失效',
      });
    }
    console.log(captcha,captchaKey,captcha != captchaKey)
    if(captcha != captchaKey){
      return Result.setData({
        code: 1,
        msg: '验证码错误！',
      });
    }

    const getDataOne = await ctx.model.User.findOne({
      where: {
        userName: data?.userName,
      },
    });
    if (!getDataOne) {
      return Result.setData({
        code: 1,
        msg: '用户不存在！',
      });
    }
    const result = await this.ctx.helper.comparePwd(data.passWord, getDataOne?.getDataValue('passWord'));



    if (!result) {
      return Result.setData({
        code: 1,
        msg: '用户名或密码错误！',
      });
    }

    const resultData = getDataOne.get('', { plain: true }) ?? {};

    const token = await ctx.app.jwt.sign({
      ...resultData as {},
    }, this.app.config.jwt.secret, {
      expiresIn: '60m', // 时间根据自己定，具体可参考jsonwebtoken插件官方说明
    });
    try {
      await ctx.app.redis.set((resultData as any).id, token, 'ex', ctx.app.config.redisExpiryTime);
    } catch (e) {
      return Result.setData({
        code: 19999,
        msg: 'redis失败',
        data: null,
      });
    }

    console.log(getDataOne.getDataValue('userName'), token);

    // 写入客户端cookies里面
    ctx.cookies.set('token', token);
    ctx.logger.info(data, '---------------------登录成功！');
    return Result.setData({
      code: 0,
      msg: '登录成功',
      data: {
        ...resultData as {},
        token,
      },
    });
  }

  /**
     * 用户退出登录
     */
  public async logout() {
    const { ctx } = this;
    const token = ctx.cookies.get('token', {
      signed: false,
    });
    const data = ctx.app.jwt.verify(token, ctx.app.config.jwt.secret);
    const redisInfo = await ctx.app.redis.del((data as any)?.id);
    ctx.logger.info(redisInfo, '退出成功');
    if (redisInfo) {
      return Result.setData({
        code: 0,
        msg: '退出成功',
      });
    }
    return Result.setData({
      code: 1,
      msg: '退出失败',
    });
  }

  /**
     * 通过token获取当前用户信息
     */
  public async getUserInfo() {
    const { ctx } = this;
    const token = ctx.cookies.get('token', {
      signed: false,
    });
    const data = ctx.app.jwt.verify(token, ctx.app.config.jwt.secret);
    const getDataOne = await ctx.model.User.findOne({
      where: {
        id: (data as any)?.id,
      },
      attributes: {
        exclude: [ 'passWord' ],
      },
      raw: true,
    });

    return Result.setData({
      code: 0,
      msg: '获取成功',
      data: {
        ...getDataOne,
      },
    });
  }

  /**
     * 获取用户列表
     */
  public async getUserList() {
    const { ctx } = this;
    const { current, pageSize }:any = ctx.request.query;
    ctx.logger.info(ctx.request.query);
    const getDataOne = await ctx.model.User.findAll({
      attributes: {
        exclude: [ 'passWord' ],
      },
      ...await ctx.helper.setPageInfo(current, pageSize),
      raw: true,
    });

    const total = await ctx.model.User.count();

    return Result.setData({
      code: 0,
      msg: '获取成功',
      data: {
        data: getDataOne,
        total,
        current,
        pageSize,
      },
    });
  }

  /**
     * 更新用户
     */
  public async getUserUpdate() {
    const { ctx } = this;
    const { id, ...body } = ctx.request.body;
    const updates = await ctx.model.User.findByPk(id);
    if (!updates) {
      return Result.setData({
        code: 1,
        msg: '参数错误,id不存在',
        data: null,
      });
    }
    const res = await updates.update({
      ...body,
      attributes: {
        exclude: [ 'passWord' ],
      },
    });

    const data = res.get('', { plain: true }) ?? {};

    return Result.setData({
      code: 0,
      msg: '修改成功',
      data: {
        ...(data as {}),
      },
    });
  }

  /**
   * 删除用户
   */
  public async delUser() {
    const { ctx } = this;
    const { id } = ctx.request.body;
    const del = await ctx.model.User.destroy({ where: { id } });

    if (del) {
      return Result.setData({
        code: 0,
        msg: '删除成功',
        data: null,
      });
    }
    return Result.setData({
      code: 0,
      msg: '删除失败',
      data: null,
    });
  }


  /**
   * 获取验证码
   */
  public async captcha() {
    const {ctx} = this
    // 验证码配置信息
    const options = {
      size: 5,                 // 验证码长度(显示几个字符)
      fontSize: 45,           // 验证码的字体大小
      width: 90,              // 验证码的宽度
      height: 40,             // 验证码的高度
      background: '#fff',   // 验证码的背景颜色
      mathMin:1,
      mathMax:30,
      mathOperator:"+,-,*,/"
    };

    ctx.response.type = 'image/svg+xml';
    const captcha = svgCaptcha.createMathExpr(options);
    ctx.logger.info("验证码为",captcha.text)
    let t = new Date().getTime() + "";
    // 写入客户端cookies里面
    ctx.cookies.set('captchaKey', t);
    // 将验证码写入redis里面
    try {
      await ctx.app.redis.set(t, captcha.text, 'ex', 60);
    } catch (e) {
      return Result.setData({
        code: 19999,
        msg: 'redis失败',
        data: null,
      });
    }
    return captcha?.data
  }
}
